<!DOCTYPE html>
<!-- saved from url=(0049)https://www.cnblogs.com/yenyuloong/p/9626658.html -->
<html lang="zh-cn"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="referrer" content="origin">
    <meta property="og:description" content="call 指令与 retn 指令 首先我们得了解 CALL 和 RETN 指令的作用，才能更好地理解调用规则，这也是先决条件。 实际上，CALL 指令就是先将下一条指令的 EIP 压栈，然后 JMP ">
    <meta http-equiv="Cache-Control" content="no-transform">
    <meta http-equiv="Cache-Control" content="no-siteapp">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园</title>
    
    <link rel="stylesheet" href="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/blog-common.min.css">
    <link id="MainCss" rel="stylesheet" href="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/bundle-watercolor-blue.min.css">
    
    <link id="mobile-style" media="only screen and (max-width: 767px)" type="text/css" rel="stylesheet" href="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/bundle-watercolor-blue-mobile.min.css">
    
    <link type="application/rss+xml" rel="alternate" href="https://www.cnblogs.com/yenyuloong/rss">
    <link type="application/rsd+xml" rel="EditURI" href="https://www.cnblogs.com/yenyuloong/rsd.xml">
    <link type="application/wlwmanifest+xml" rel="wlwmanifest" href="https://www.cnblogs.com/yenyuloong/wlwmanifest.xml">
    <script src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/amp4ads-host-v0.js.下载"></script><script async="" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/analytics.js.下载"></script><script src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/jquery-2.2.0.min.js.下载"></script>
    <script src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/blog-common.min.js.下载"></script>
    <script>
        var currentBlogId = 433620;
        var currentBlogApp = 'yenyuloong';
        var cb_enable_mathjax = false;
        var isLogined = false;
        var skinName = 'watercolor-blue';
    </script>
    
    
    
<link rel="preload" href="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/f.txt" as="script"><script type="text/javascript" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/f.txt"></script><script src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/pubads_impl_2020043001.js.下载" async=""></script><link rel="prefetch" href="https://tpc.googlesyndication.com/safeframe/1-0-37/html/container.html"></head>
<body>
    <a name="top"></a>
    
    <div id="maincontainer">
	<div id="header">
		
<h1><a id="Header1_HeaderTitle" class="headermaintitle HeaderMainTitle" href="https://www.cnblogs.com/yenyuloong/">Yenyu Loong's Programming Blog</a>
</h1>
<div id="tagline">
Love learning, love thinking, love coding.
</div>
<div id="menubar">
<div id="blogstats"><span>posts(
19)</span>
<span>comments(
2)</span>
<span>trackbacks(
0)</span>

</div>
<ul>
    <li><a id="blog_nav_sitehome" class="home" href="https://www.cnblogs.com/">
博客园</a>
</li>
    <li>
<a id="blog_nav_contact" class="contact" href="https://msg.cnblogs.com/send/yenyuloong">
联系</a></li>
    <li>
<a id="blog_nav_rss" class="menu" href="javascript:void(0)" data-rss="https://www.cnblogs.com/yenyuloong/rss/">
订阅</a></li>
    <li>
<a id="blog_nav_admin" class="admin" href="https://i.cnblogs.com/">
管理</a>
</li>
</ul>
<script>
    $("#blog_nav_sitehome").removeClass("menu").addClass("home");
    $("#blog_nav_contact").removeClass("menu").addClass("contact");
    $("#blog_nav_contact").removeClass("menu").addClass("contact");
    $("#blog_nav_admin").removeClass("menu").addClass("admin");
</script>

</div>





	</div>
	<div id="content">
		<div id="left">
			
				
<div id="sidebar_news" class="newsItem"><div class="container">
	<div class="containerheader"><h3>公告</h3></div>
	<div class="containercontent">
		
<div id="blog-news">
    <a href="http://home.cnblogs.com/u/yenyuloong/"><img class="divBlock" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/20180522101032.png"></a>

<font size="-3">
<table border="1" width="210" align="center" style="border-collapse: collapse">
<tbody><tr>
<th>QQ</th>
<th><a target="_blank" href="http://wpa.qq.com/msgrd?v=3&amp;uin=1324578506&amp;site=qq&amp;menu=yes" style="color: rgba(165, 42, 42, 1)">1324578506</a></th>
</tr>
<tr>
<th>邮箱</th>
<th><a href="mailto:yenyu.loong@foxmail.com" style="color: rgba(0, 0, 255, 1)">yenyu.loong@foxmail.com</a></th>
</tr>
<tr>
<th>博客</th>
<th><a href="http://yenyuloong.cnblogs.com/" style="color: rgba(0, 128, 0, 1)">yenyuloong.cnblogs.com</a></th>
</tr>
</tbody></table>
</font>

<br>

<p>
</p><div id="myTime">
	
</div>
<p></p>
<p>
<a style="color: rgba(128, 0, 128, 1)">/* 访客统计：*/</a>
<br>
</p><div align="left"><a href="https://www.amazingcounters.com/"><img border="0" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/counter.php" alt="AmazingCounters.com"></a></div>

<p></p>
    <div id="profile_block">
        昵称：
        <a href="https://home.cnblogs.com/u/yenyuloong/">
            yenyuloong
        </a>
        <br>
        园龄：
        <a href="https://home.cnblogs.com/u/yenyuloong/" title="入园时间：2018-05-22">
            1年11个月
        </a>
        <br>
        粉丝：
        <a href="https://home.cnblogs.com/u/yenyuloong/followers/">
            0
        </a>
        <br>
        关注：
        <a href="https://home.cnblogs.com/u/yenyuloong/followees/">
            0
        </a>
        <div id="p_b_follow">
<a href="javascript:void(0)" onclick="follow(&#39;c22e4c23-e028-4293-aead-08d5bd673bdc&#39;)">+加关注</a></div>
        <script>getFollowStatus('c22e4c23-e028-4293-aead-08d5bd673bdc');</script>
    </div>
</div>
	</div>
</div>

</div>

<div id="sidebar_ad"></div>
				<div id="blog-sidecolumn">
<!-- 搜索 -->
<div id="sidebar_search" class="sidebar-block">
    <div id="sidebar_search" class="mySearch">
        <h3 class="catListTitle">搜索</h3>
        <div id="sidebar_search_box">
            <div id="widget_my_zzk" class="div_my_zzk">
                <input type="text" id="q" onkeydown="return zzk_go_enter(event);" class="input_my_zzk">&nbsp;<input onclick="zzk_go()" type="button" value="找找看" id="btnZzk" class="btn_my_zzk">
            </div>
            <div id="widget_my_google" class="div_my_zzk">
                <input type="text" name="google_q" id="google_q" onkeydown="return google_go_enter(event);" class="input_my_zzk">&nbsp;<input onclick="google_go()" type="button" value="谷歌搜索" class="btn_my_zzk">
            </div>
        </div>
    </div>
</div>

<!-- 常用链接 -->
<div id="sidebar_shortcut" class="sidebar-block">
    <div class="container">
    <div class="containerheader">
        <h3 class="catListTitle">
            
常用链接
</h3>
    </div>
    <ul class="containercontent">
                <li>
                    

<a href="https://www.cnblogs.com/yenyuloong/p/" title="我的博客的随笔列表">我的随笔</a>
</li>
                <li>
                    

<a href="https://www.cnblogs.com/yenyuloong/MyComments.html" title="我的发表过的评论列表">我的评论</a>
</li>
                <li>
                    

<a href="https://www.cnblogs.com/yenyuloong/OtherPosts.html" title="我评论过的随笔列表">我的参与</a>
</li>
                <li>
                    

<a href="https://www.cnblogs.com/yenyuloong/RecentComments.html" title="我的博客的评论列表">最新评论</a>
</li>
                <li>
                    

<a href="https://www.cnblogs.com/yenyuloong/tag/" title="我的博客的标签列表">我的标签</a>
</li>
        
    </ul>
    <div id="itemListLin_con" style="display: none;">
        
    </div>
</div>


</div>

<!-- 最新随笔 -->



<!-- 我的标签 -->
<div id="sidebar_toptags" class="sidebar-block">
    
</div>

<!-- 积分与排名 -->


<!-- 随笔分类、随笔档案、文章分类、新闻分类、相册、链接 -->
<div id="sidebar_categories">
    
		<div class="container">
			<div class="containerheader"><h3>

随笔分类


</h3></div>
			
				
					<ul class="containercontent">
				
					<li>
<a href="https://www.cnblogs.com/yenyuloong/category/1221773.html" rel="" target="">
    Windows API(11)
</a>
</li>
					<li>
<a href="https://www.cnblogs.com/yenyuloong/category/1223598.html" rel="" target="">
    Windows 编程散记(1)
</a>
</li>
					<li>
<a href="https://www.cnblogs.com/yenyuloong/category/1297718.html" rel="" target="">
    编程内功与心法(6)
</a>
</li>
					<li>
<a href="https://www.cnblogs.com/yenyuloong/category/1225532.html" rel="" target="">
    算法和数据结构(1)
</a>
</li>
				
					</ul>
				
			
			<div class="containerfooter"></div>
		</div>		
		<div class="container">
			<div class="containerheader"><h3>

随笔档案


</h3></div>
			
				
					<ul class="containercontent">
				
					<li>
<a href="https://www.cnblogs.com/yenyuloong/archive/2019/01.html" rel="" target="">
    2019年1月(1)
</a>
</li>
					<li>
<a href="https://www.cnblogs.com/yenyuloong/archive/2018/09.html" rel="" target="">
    2018年9月(5)
</a>
</li>
					<li>
<a href="https://www.cnblogs.com/yenyuloong/archive/2018/06.html" rel="" target="">
    2018年6月(5)
</a>
</li>
					<li>
<a href="https://www.cnblogs.com/yenyuloong/archive/2018/05.html" rel="" target="">
    2018年5月(8)
</a>
</li>
				
					</ul>
				
			
			<div class="containerfooter"></div>
		</div>		


</div>

<!-- 最新评论 -->
<div id="sidebar_recentcomments" class="sidebar-block">
    <div class="container">
<div class="containerheader"><h3>最新评论
	</h3></div>
	<div class="RecentCommentBlock">
        <ul>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/yenyuloong/p/9626658.html">1. Re:__cdecl、__stdcall、__fastcall 与 __pascal 浅析</a></li>
                    <li class="recent_comment_body">@ ztzheng100vs 可以查看反汇编...</li>
                    <li class="recent_comment_author">--Asele</li>
                    <li class="recent_comment_title"><a href="https://www.cnblogs.com/yenyuloong/p/9626658.html">2. Re:__cdecl、__stdcall、__fastcall 与 __pascal 浅析</a></li>
                    <li class="recent_comment_body">请问博文中的关于内存地址的汇编编码是用什么编译器执行的，怎么查看</li>
                    <li class="recent_comment_author">--ztzheng100</li>
        </ul>
    </div>
</div>


</div>



<!-- 阅读排行榜 -->
<div id="sidebar_topviewedposts" class="sidebar-block">
    <div class="container">
<div class="containerheader"><h3>阅读排行榜</h3></div>
	<div id="TopViewPostsBlock">
        <ul style="word-break:break-all">
                    <li>
                        <a href="https://www.cnblogs.com/yenyuloong/p/9626658.html">
                            1. __cdecl、__stdcall、__fastcall 与 __pascal 浅析(2077)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/yenyuloong/p/9071148.html">
                            2. 我的第一个 Windows 窗口程序（1）(965)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/yenyuloong/p/9076528.html">
                            3. GDI 设备环境句柄（2）(762)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/yenyuloong/p/9121896.html">
                            4. GDI 边框绘制函数（8）(360)
                        </a>
                    </li>
                    <li>
                        <a href="https://www.cnblogs.com/yenyuloong/p/9629749.html">
                            5. 通过分析反汇编还原 C 语言 if…else 结构(354)
                        </a>
                    </li>
        </ul>
    </div>

</div>


</div>

<!-- 评论排行榜 -->
<div id="sidebar_topcommentedposts" class="sidebar-block">
    <div class="container">
<div class="containerheader">
<h3>评论排行榜</h3>
</div>
	<div id="TopFeedbackPostsBlock">
        <ul style="word-break:break-all">
                    <li>
                        <a href="https://www.cnblogs.com/yenyuloong/p/9626658.html">
                            1. __cdecl、__stdcall、__fastcall 与 __pascal 浅析(2)
                        </a>
                    </li>
        </ul>
    </div>
</div>


</div>

<!-- 推荐排行榜 -->
<div id="sidebar_topdiggedposts" class="sidebar-block">
    
</div></div>
                    <script>loadBlogSideColumn();</script>
							
		</div>
		<div id="right">
			<div id="post_detail">
<div class="container">
	<div class="containerheader"><h3>View Post</h3></div>
	<div class="containercontent">
	<div class="post">
		<h2>
			
<a id="cb_post_title_url" class="postTitle2" href="https://www.cnblogs.com/yenyuloong/p/9626658.html">__cdecl、__stdcall、__fastcall 与 __pascal 浅析</a>

		</h2>
		
<div id="cnblogs_post_body" class="blogpost-body ">
    <p><font size="2"></font></p> <p><strong><font size="4">call 指令与 retn 指令</font></strong></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 首先我们得了解 CALL 和 RETN 指令的作用，才能更好地理解调用规则，这也是先决条件。</font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 实际上，CALL 指令就是先将下一条指令的 EIP 压栈，然后 JMP 跳转到对应的函数的首地址，当执行完函数体后，通过 RETN 指令从堆栈中弹出 EIP，程序就可以继续执行 CALL 的下一条指令。</font></p> <p><strong><font size="4">__cdecl 与 __stdcall 调用规则</font></strong></p> <p><font size="2">&nbsp;&nbsp;&nbsp; C/C++ 中不同的函数调用规则会生成不同的机器代码，产生不同的微观效果，接下来让我们一起来浅析四种调用规则的原理和它们各自的异同。首先我们通过一段 C 语言代码来引导我们的浅析过程。</font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 这里我们编写了三个函数，它们的功能都是返回两个参数的相加结果，只是每个函数都有不一样的调用规则。</font></p> <p><font size="2"><a href="https://img2018.cnblogs.com/blog/1405458/201809/1405458-20180911113956721-386326953.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/1405458-20180911113957633-1575450291.png" width="346" height="516"></a></font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 我们使用 printf 函数主要是为了在 OllyDBG 中能够快速下断点，以确定后边调用三个函数的位置，便于分析。在这里我给每个函数都用了内联的 NOP 指令来分隔开，图中也用红框标明，这样可以便于区分每个函数的调用过程。通过一些简单的步骤，我们用 OllyDBG 查看了编译后代码的“真面目”。代码中有 4 个 CALL，第一个是 printf，我们不关心这个。后面三个分别是具有 __cdecl，__stdcall，__fastcall 调用规则的函数 CALL（这里我已经做了注释）。</font></p> <p><a href="https://img2018.cnblogs.com/blog/1405458/201809/1405458-20180911113958425-1234075207.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/1405458-20180911113959327-835562972.png" width="820" height="385"></a></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 在这里为了循序渐进，我们先介绍 __cdecl 与 __stdcall 调用规则，后面我们会接着浅析 __fastcall 调用规则。</font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 首先，我们得明白一个教条（其实也是自己概括的），那就是 —— 调用规则的区别产生其实就是由于调用者与被调用者之间的“责任分配”问题。</font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 代码段中的第 2 个就是 __cdecl 调用规则的 CALL。__cdecl 是 C/C++、MFC 默认的调用规则。我们可以看到，在执行 CALL 之前，程序会将参数按照从右到左的方式压栈，这里是两个整型参数，每压栈一个 ESP 都会减 4，这样下来 ESP 会减少 8，然后 CALL 这个函数。常规地，我们可以看到，这个 CALL 里面参数的处理和通常情况下一致，先将 EBP 压栈保存现场，然后使 EBP 重合于 ESP，再通过 EBP + 偏移地址来取得两个参数值，赋值再累加到 EAX 中，EAX 将作为返回值给调用者使用，还原 EBP 现场，调用 RETN 返回到调用者。最后，使得 ESP 加 8。哎！这刚好和开头对称嘛！为了堆栈平衡，ESP 最终又被拉回到了 CALL 之前的位置。我们暂且可以小结一下，实际上<strong><font style="background-color: #ffff00">在 __cdecl 调用规则中，需要调用者来负责清栈操作（由调用者将 ESP 拉高以维持堆栈平衡）。</font></strong></font></p> <p><a href="https://img2018.cnblogs.com/blog/1405458/201809/1405458-20180911114000000-1760140031.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/1405458-20180911114000663-1544018928.png" width="706" height="109"></a></p> <p><font size="2"></font>&nbsp;</p> <p><font size="2">&nbsp;&nbsp;&nbsp; 代码段中的第 3 个是 __stdcall 调用规则的 CALL。__stdcall 调用规则在 Win32 API 函数中用的比较多。跟 __cdecl 一样，在执行 CALL 之前，程序会先将参数从右到左依次压栈，我们跟进 CALL 里面，可以看到以下的反汇编代码，我们很容易发现，除了最后一条指令，其他的指令与 __cdecl 调用规则是基本一样的。最后一条指令是“RETN 0x8”，这是什么意思呢？实际上呢，就相当于先执行“ADD ESP, 0x8”再执行“POP EIP” 。换言之，就是将 ESP 加 8，然后正常 RETN 返回到调用者。</font></p> <p><a href="https://img2018.cnblogs.com/blog/1405458/201809/1405458-20180911114001312-1193315344.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/1405458-20180911114002137-398697761.png" width="706" height="106"></a></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 我们不难发现<strong><font style="background-color: #ffff00"><font style="background-color: #ffffff">，</font>__stdcall 调用规则使得被调用者来执行清栈操作（由被调用者函数自身将 ESP 拉高以维持堆栈平衡）</font></strong>，这也是 __stdcall 与 __cdecl 调用规则的最根本的区别。</font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; __cdecl 偏向于把责任分配给调用者，动脑筋想想，我们的程序在 CALL __cdecl 调用规则的函数之前，把参数从右到左依次压栈，CALL 返回后，剩下的清栈操作都交给调用者处理，调用者负责拉高 ESP。再回来想想 __stdcall，在 CALL 中将调用者的 EBP 压栈以保存现场，然后使 EBP 对齐于 ESP，然后通过 EBP + 偏移地址取得参数，并且经过加法得到 EAX 返回值，从堆栈弹出 EBP 恢复现场，但是最后不一样的地方，程序将执行 “RETN 0x8” 将 ESP 拉回之前的 ESP + 8 的位置，换言之，被调用者将负责清栈操作。这就是之前所谓的“责任分配”的区别。</font></p> <p><font size="2"></font>&nbsp;</p> <p><strong><font size="4">__fastcall 调用规则</font></strong></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 不难揣测 fastcall 的英文意思貌似是“快速调用”，这一点与它的调用规则息息相关，它的快速是有原因的，让我们继续来看看之前那张反汇编的截图，代码段中的第 4 个就是 __fastcall 调用规则的 CALL。进 CALL 前，出乎意料地，程序将两个参数从右到左分别传给了 EDX，ECX 寄存器，讲到这里，学过计算机系统相关知识的人很容易理解为什么这叫“快速调用”了，寄存器比内存快很多很多倍，可以认为传参给寄存器，要比在内存中更快得多，效率更高。</font></p> <p><a href="https://img2018.cnblogs.com/blog/1405458/201809/1405458-20180911114002818-1446089391.png"><img title="image" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="image" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/1405458-20180911114003602-1036241416.png" width="714" height="175"></a></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 由于参数是直接传递给了寄存器，堆栈并未发生改变，在 CALL 中，EBP 压栈，EBP 和 ESP 对齐之后，ESP 减 8，这个操作有点像对局部变量分配堆栈空间（<strong><a href="https://www.cnblogs.com/yenyuloong/p/9621538.html" target="_blank">这里</a></strong>有我之前一篇博客，对局部变量的存放规则做了浅析），然后程序将 EDX，ECX 分别赋值给 EBP – 8 与 EBP – 4 这两个地址，这个过程相当于用寄存器给局部变量赋值，接下来运算结果将保存在 EAX 中，ESP 归位，EBP 恢复现场，最后 RETN 返回调用者领空。</font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 本例只传送了两个整数型参数。</font><font size="2">其实呢，对于 __fastcall 调用规则，</font><font size="2">左边开始的两个不大于4字节（int）的参数分别放在ECX和EDX寄存器，其余的参数仍旧自右向左压栈传送。并且<font style="background-color: #ffff00">，<strong>__fastcall 调用规则使得被调用者负责清理栈的操作（由被调用者函数自身将 ESP 拉高以维持堆栈平衡）</strong></font>，这一点和 __stdcall 一样。</font></p> <p><font size="2"></font>&nbsp;</p> <p><strong><font size="4">__pascal 调用规则</font></strong></p> <p><font size="2">&nbsp;&nbsp;&nbsp; __pascal 是用于 Pascal / Delphi 编程语言的调用规则，C/C++ 中也可以使用这种调用规则。简单地说，__pascal 调用规则与 __stdcall 不同的地方就是压栈顺序恰恰相反，前面讲到的三种调用规则的压栈顺序都是从右到左依次入栈<font style="background-color: #ffff00"><strong>，__pascal 则是从左到右依次入栈。</strong><font style="background-color: #ffffff">并且，</font><strong>被调用者（函数自身）将自行完成清栈操作</strong></font>，这和 __stdcall，__fastcall 一样。由于比较简单，我就没有做出示例。</font></p> <p><font size="2"></font></p>  <p>&nbsp;</p> <p><font size="4"><strong>小结</strong></font></p> <p><font size="2">&nbsp;&nbsp;&nbsp; 做个表格来小结一下，很直观就能看出这四种调用规则的异同：</font></p> <table cellspacing="0" cellpadding="2" width="643" border="0"> <tbody> <tr> <td valign="top" width="156"> <p align="center"><font size="3" face="Consolas"><strong>调用规则</strong></font></p></td> <td valign="top" width="309"> <p align="center"><font size="3" face="Consolas"><strong>入栈顺序</strong></font></p></td> <td valign="top" width="176"> <p align="center"><font size="3" face="Consolas"><strong>清栈责任</strong></font></p></td></tr> <tr> <td valign="top" width="156"> <p align="center"><font size="2" face="Consolas">__cdecl</font></p></td> <td valign="top" width="309"> <p align="center"><font size="2" face="Consolas">从右到左</font></p></td> <td valign="top" width="176"> <p align="center"><font size="2" face="Consolas">调用者</font></p></td></tr> <tr> <td valign="top" width="156"> <p align="center"><font size="2" face="Consolas">__stdcall</font></p></td> <td valign="top" width="309"> <p align="center"><font size="2" face="Consolas">从右到左</font></p></td> <td valign="top" width="176"> <p align="center"><font size="2" face="Consolas">被调用者</font></p></td></tr> <tr> <td valign="top" width="156"> <p align="center"><font size="2" face="Consolas">__fastcall</font></p></td> <td valign="top" width="309"> <p align="center"><font size="2" face="Consolas">从右到左（先 EDX、ECX，再到堆栈）</font></p></td> <td valign="top" width="176"> <p align="center"><font size="2" face="Consolas">被调用者</font></p></td></tr> <tr> <td valign="top" width="156"> <p align="center"><font size="2" face="Consolas">__pascal</font></p></td> <td valign="top" width="309"> <p align="center"><font size="2" face="Consolas">从左到右</font></p></td> <td valign="top" width="176"> <p align="center"><font size="2" face="Consolas">被调用者</font></p></td></tr></tbody></table>
</div>
<div id="MySignature"></div>
<div class="clear"></div>
<div id="blog_post_info_block"><div id="BlogPostCategory">
    分类: 
            <a href="https://www.cnblogs.com/yenyuloong/category/1297718.html" target="_blank">编程内功与心法</a></div>


    <div id="blog_post_info">
<div id="green_channel">
        <a href="javascript:void(0);" id="green_channel_digg" onclick="DiggIt(9626658,cb_blogId,1);green_channel_success(this,&#39;谢谢推荐！&#39;);">好文要顶</a>
        <a id="green_channel_follow" onclick="follow(&#39;c22e4c23-e028-4293-aead-08d5bd673bdc&#39;);" href="javascript:void(0);">关注我</a>
    <a id="green_channel_favorite" onclick="AddToWz(cb_entryId);return false;" href="javascript:void(0);">收藏该文</a>
    <a id="green_channel_weibo" href="javascript:void(0);" title="分享至新浪微博" onclick="ShareToTsina()"><img src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/icon_weibo_24.png" alt=""></a>
    <a id="green_channel_wechat" href="javascript:void(0);" title="分享至微信" onclick="shareOnWechat()"><img src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/wechat.png" alt=""></a>
</div>
<div id="author_profile">
    <div id="author_profile_info" class="author_profile_info">
            <a href="https://home.cnblogs.com/u/yenyuloong/" target="_blank"><img src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/20180522101032(1).png" class="author_avatar" alt=""></a>
        <div id="author_profile_detail" class="author_profile_info">
            <a href="https://home.cnblogs.com/u/yenyuloong/">yenyuloong</a><br>
            <a href="https://home.cnblogs.com/u/yenyuloong/followees/">关注 - 0</a><br>
            <a href="https://home.cnblogs.com/u/yenyuloong/followers/">粉丝 - 0</a>
        </div>
    </div>
    <div class="clear"></div>
    <div id="author_profile_honor"></div>
    <div id="author_profile_follow">
                <a href="javascript:void(0);" onclick="follow(&#39;c22e4c23-e028-4293-aead-08d5bd673bdc&#39;);return false;">+加关注</a>
    </div>
</div>
<div id="div_digg">
    <div class="diggit" onclick="votePost(9626658,&#39;Digg&#39;)">
        <span class="diggnum" id="digg_count">0</span>
    </div>
    <div class="buryit" onclick="votePost(9626658,&#39;Bury&#39;)">
        <span class="burynum" id="bury_count">0</span>
    </div>
    <div class="clear"></div>
    <div class="diggword" id="digg_tips">
    </div>
</div>

<script type="text/javascript">
    currentDiggType = 0;
</script></div>
    <div class="clear"></div>
    <div id="post_next_prev">

    <a href="https://www.cnblogs.com/yenyuloong/p/9621538.html" class="p_n_p_prefix">« </a> 上一篇：    <a href="https://www.cnblogs.com/yenyuloong/p/9621538.html" title="发布于 2018-09-10 18:10">ESP、EBP、CALL 指令与局部变量浅析</a>
    <br>
    <a href="https://www.cnblogs.com/yenyuloong/p/9629749.html" class="p_n_p_prefix">» </a> 下一篇：    <a href="https://www.cnblogs.com/yenyuloong/p/9629749.html" title="发布于 2018-09-11 19:25">通过分析反汇编还原 C 语言 if…else 结构</a>

</div>
</div>
		<p class="postfoot">
			posted on 
<span id="post-date">2018-09-11 11:40</span>&nbsp;
<a href="https://www.cnblogs.com/yenyuloong/">yenyuloong</a>&nbsp;
阅读(<span id="post_view_count">2077</span>)&nbsp;
评论(<span id="post_comment_count">2</span>)&nbsp;
<a href="https://i.cnblogs.com/EditPosts.aspx?postid=9626658" rel="nofollow">编辑</a>&nbsp;
<a href="javascript:void(0)" onclick="AddToWz(9626658);return false;">收藏</a>
		</p>
	</div>
	
	
	</div>
</div>
	
<script src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/highlight.min.js.下载"></script>
<script>markdown_highlight();</script>
<script>
    var allowComments = true, cb_blogId = 433620, cb_blogApp = 'yenyuloong', cb_blogUserGuid = 'c22e4c23-e028-4293-aead-08d5bd673bdc';
    var cb_entryId = 9626658, cb_entryCreatedDate = '2018-09-11 11:40', cb_postType = 1; 
    loadViewCount(cb_entryId);
    loadSideColumnAd();
</script><a name="!comments"></a>
<div id="blog-comments-placeholder">

<div id="comment_pager_top">
    
</div>

<div class="container">
	<div class="containerheader"><h3>View Comments</h3></div>	
	<div id="comments" class="containercontent">
		<div class="feedbackNoItems"></div>
				<div class="post">
					<h5>
						
<a href="https://www.cnblogs.com/yenyuloong/p/9626658.html#4285597" class="layer">#1楼</a>
<a name="4285597" id="comment_anchor_4285597"></a>


						&nbsp;&nbsp;

<span class="comment_actions">
    
    
    
    
</span>


					</h5>
					
<div id="comment_body_4285597" data-format-type="Ubb" class="blog_comment_body cnblogs-ubb">
    请问博文中的关于内存地址的汇编编码是用什么编译器执行的，怎么查看
</div>
        <div class="comment_vote">
            <span class="comment_error" style="color: red"></span>
            <a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(4285597, &#39;Digg&#39;, this.parentElement, false);">
                支持(0)
            </a>
            <a href="javascript:void(0);" class="comment_burry" onclick="return voteComment(4285597, &#39;Bury&#39;, this.parentElement, false);">
                反对(0)
            </a>
        </div>
        

					<div class="postfoot">
						
<span class="comment_date">2019-06-23 16:00</span>

 | 

            <a id="a_comment_author_4285597" href="https://home.cnblogs.com/u/1293764/" target="_blank">ztzheng100</a>

					</div>
				</div>
				<div class="post">
					<h5>
						
<a href="https://www.cnblogs.com/yenyuloong/p/9626658.html#4366610" class="layer">#2楼</a>
<a name="4366610" id="comment_anchor_4366610"></a>

        <span id="comment-maxId" style="display:none">4366610</span>
        <span id="comment-maxDate" style="display:none">2019/9/23 下午2:30:04</span>

						&nbsp;&nbsp;

<span class="comment_actions">
    
    
    
    
</span>


					</h5>
					
<div id="comment_body_4366610" data-format-type="Ubb" class="blog_comment_body cnblogs-ubb">
    <a href="https://www.cnblogs.com/yenyuloong/p/9626658.html#4285597" title="查看所回复的评论" onclick="commentManager.renderComments(0,50,4285597);">@</a>
ztzheng100<br>vs 可以查看反汇编
</div>
        <div class="comment_vote">
            <span class="comment_error" style="color: red"></span>
            <a href="javascript:void(0);" class="comment_digg" onclick="return voteComment(4366610, &#39;Digg&#39;, this.parentElement, false);">
                支持(0)
            </a>
            <a href="javascript:void(0);" class="comment_burry" onclick="return voteComment(4366610, &#39;Bury&#39;, this.parentElement, false);">
                反对(0)
            </a>
        </div>
        

					<div class="postfoot">
						
<span class="comment_date">2019-09-23 14:30</span>

 | 

            <a id="a_comment_author_4366610" href="https://www.cnblogs.com/roadroad/" target="_blank">Asele</a>

					</div>
				</div>
	</div>
</div>

<div id="comment_pager_bottom">
    
</div>


</div>
<script>
    var commentManager = new blogCommentManager();
    commentManager.renderComments(0);
</script>

<div id="comment_form" class="commentform">
    <a name="commentform"></a>
    <div id="divCommentShow"></div>
    <div id="comment_nav"><span id="span_refresh_tips"></span><a href="javascript:void(0);" onclick="return RefreshCommentList();" id="lnk_RefreshComments" runat="server" clientidmode="Static">刷新评论</a><a href="https://www.cnblogs.com/yenyuloong/p/9626658.html#" onclick="return RefreshPage();">刷新页面</a><a href="https://www.cnblogs.com/yenyuloong/p/9626658.html#top">返回顶部</a></div>
    <div id="comment_form_container" style="visibility: visible;"><div class="login_tips">
    注册用户登录后才能发表评论，请 
    <a rel="nofollow" href="javascript:void(0);" class="underline" onclick="return login(&#39;commentform&#39;);">登录</a>
     或 
    <a rel="nofollow" href="javascript:void(0);" class="underline" onclick="return register();">注册</a>，
    <a href="https://www.cnblogs.com/">访问</a> 网站首页。
</div></div>
    <div class="ad_text_commentbox" id="ad_text_under_commentbox"></div>
    <div id="ad_t2"><a href="http://www.ucancode.com/index.htm" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T2-ucancode&#39;)">【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库</a><br><a href="https://developer.aliyun.com/article/727629?utm_content=g_1000088946" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T2-阿里云开发者社区&#39;)">【推荐】阿里云研究中心16本白皮书全套下载！涵盖AI，云计算等领域</a><br><a href="https://developer.aliyun.com/article/727136?utm_content=g_1000104144" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T2-阿里云开发者社区&#39;)">【推荐】独家下载 |《大数据工程师必读手册》揭秘阿里如何玩转大数据</a><br></div>
    <div id="opt_under_post"></div>
    <script async="async" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/gpt.js.下载"></script>
    <script>
        var googletag = googletag || {};
        googletag.cmd = googletag.cmd || [];
    </script>
    <script>
        googletag.cmd.push(function () {
            googletag.defineSlot("/1090369/C1", [300, 250], "div-gpt-ad-1546353474406-0").addService(googletag.pubads());
            googletag.defineSlot("/1090369/C2", [468, 60], "div-gpt-ad-1539008685004-0").addService(googletag.pubads());
            googletag.pubads().enableSingleRequest();
            googletag.enableServices();
        });
    </script>
    <div id="cnblogs_c1" class="c_ad_block">
        <div id="div-gpt-ad-1546353474406-0" style="height:250px; width:300px;" data-google-query-id="COjZ-a7yq-kCFRkJXAodgsoJ0w"><div id="google_ads_iframe_/1090369/C1_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C1_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C1_0" width="300" height="250" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" style="border: 0px; vertical-align: bottom;" data-google-container-id="1" data-load-complete="true" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/saved_resource.html"></iframe></div></div>
    </div>
    <div id="under_post_news"><div class="recomm-block"><b>相关博文：</b><br>·  <a title="__cdecl,__stdcall,__fastcall,__pascal,__thiscall 的区别" href="https://www.cnblogs.com/john-h/p/6276828.html" target="_blank" onclick="clickRecomItmem(6276828)">__cdecl,__stdcall,__fastcall,__pascal,__thiscall 的区别</a><br>·  <a title=" __cdecl   __fastcall与   __stdcall    " href="https://www.cnblogs.com/lauer0246/archive/2009/01/08/1372063.html" target="_blank" onclick="clickRecomItmem(1372063)"> __cdecl   __fastcall与   __stdcall    </a><br>·  <a title="_cdecl、_stdcall、_fastcall和_thiscall整理" href="https://www.cnblogs.com/zhank/archive/2009/09/10/1563706.html" target="_blank" onclick="clickRecomItmem(1563706)">_cdecl、_stdcall、_fastcall和_thiscall整理</a><br>·  <a title="__stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介" href="https://www.cnblogs.com/lidabo/p/3274713.html" target="_blank" onclick="clickRecomItmem(3274713)">__stdcall,__cdecl,_cdecl,_stdcall,。__fastcall,_fastcall 区别简介</a><br>·  <a title="__cdecl 、__fastcall、__stdcall" href="https://www.cnblogs.com/jiu0821/p/4219545.html" target="_blank" onclick="clickRecomItmem(4219545)">__cdecl 、__fastcall、__stdcall</a><br>»  <a target="_blank" href="https://recomm.cnblogs.com/blogpost/9626658">更多推荐...</a><div id="cnblogs_t5"><a href="https://developer.aliyun.com/article/714279?utm_content=g_1000088939" target="_blank" onclick="ga(&#39;send&#39;, &#39;event&#39;, &#39;Link&#39;, &#39;click&#39;, &#39;T5-阿里云开发者社区&#39;)">阿里毕玄16篇文章，深度讲解Java开发、系统设计、职业发展</a></div></div></div>
    <div id="cnblogs_c2" class="c_ad_block">
        <div id="div-gpt-ad-1539008685004-0" style="height:60px; width:468px;" data-google-query-id="COnZ-a7yq-kCFRkJXAodgsoJ0w">
            
        <div id="google_ads_iframe_/1090369/C2_0__container__" style="border: 0pt none;"><iframe id="google_ads_iframe_/1090369/C2_0" title="3rd party ad content" name="google_ads_iframe_/1090369/C2_0" width="468" height="60" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" style="border: 0px; vertical-align: bottom;" data-google-container-id="2" data-load-complete="true" src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/saved_resource(1).html"></iframe></div></div>
    </div>
    <div id="under_post_kb">
<div class="itnews c_ad_block">
    <b>最新 IT 新闻</b>:
    <br>
 ·              <a href="https://news.cnblogs.com/n/661679/" target="_blank">作者和阅文的“战争”，让网文死于2020年</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/661678/" target="_blank">国外高人上课：月收入过亿休闲手游如何做剧情？</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/661677/" target="_blank">拼多多疯狂烧钱，“拼夕夕”要成“拼爹爹”？</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/661676/" target="_blank">急于卖车的懂车帝“翻车”</a>
            <br>
 ·              <a href="https://news.cnblogs.com/n/661675/" target="_blank">柳青：滴滴核心业务盈利，暂无裁员计划</a>
            <br>
    » <a href="https://news.cnblogs.com/" title="IT 新闻" target="_blank">更多新闻...</a>
</div></div>
    <div id="HistoryToday" class="c_ad_block"></div>
    <script type="text/javascript">
        fixPostBody();
        deliverBigBanner();
setTimeout(function() { incrementViewCount(cb_entryId); }, 50);        deliverAdT2();
        deliverAdC1();
        deliverAdC2();
        loadNewsAndKb();
        loadBlogSignature();
LoadPostCategoriesTags(cb_blogId, cb_entryId);        LoadPostInfoBlock(cb_blogId, cb_entryId, cb_blogApp, cb_blogUserGuid);
        GetPrevNextPost(cb_entryId, cb_blogId, cb_entryCreatedDate, cb_postType);
        loadOptUnderPost();
        GetHistoryToday(cb_blogId, cb_blogApp, cb_entryCreatedDate);
    </script>
</div></div>


		</div>
	</div>	
	<div class="clearing">&nbsp;</div>
</div>
<div id="footer">
	Powered by:<br> 
<a id="Footer1_Hyperlink1" name="Hyperlink1" href="http://scottwater.com/blog"><img src="./__cdecl、__stdcall、__fastcall 与 __pascal 浅析 - yenyuloong - 博客园_files/100x30_Logo.gif" alt=""></a>
<a href="https://www.cnblogs.com/" id="footer_site_link">博客园</a><br>
Copyright © 2020 yenyuloong
<br><span id="poweredby">Powered by .NET Core on Kubernetes</span>



</div>


    <div id="page_end_html">
        <div id="footer" align="center">
<a href="https://github.com/yenyuloong/" style="color: rgba(0, 128, 0, 1)" target="_blank">Github主页</a>
 | 
<a href="mailto:yenyu.loong@foxmail.com" style="color: rgba(0, 128, 0, 1)">邮件联系</a>
</div>
    </div>

</body></html>